#include "xvideothread.h"
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <xfilter.h>
#include <iostream>
using namespace cv;

static VideoCapture cap1;
static VideoCapture cap2;
static VideoWriter vw;


bool XVideoThread::Open(const std::string file)
{
    mutex.lock();
    bool re =cap1.open(file);
    mutex.unlock();
    Seek(0);
    if (!re)
        return re;
    fps = cap1.get(CAP_PROP_FPS);
    width = cap1.get(CAP_PROP_FRAME_WIDTH);
    height = cap1.get(CAP_PROP_FRAME_HEIGHT);
    srcFile = file;

    double count = cap1.get(CAP_PROP_FRAME_COUNT);
    totalMs = (count/(double)fps)*1000;
    if(fps<=0) fps= 25;
    return true;
}

bool XVideoThread::Open2(const std::string file)
{
    mutex.lock();
    bool re =cap2.open(file);
    mutex.unlock();
    Seek(0);
    if (!re)
        return re;
    fps = cap2.get(CAP_PROP_FPS);
    width2 = cap2.get(CAP_PROP_FRAME_WIDTH);
    height2 = cap2.get(CAP_PROP_FRAME_HEIGHT);

    if(fps<=0) fps= 25;
    return true;

}

double XVideoThread::GetPos()
{
    double pos=0;
    // mutex.lock();
    if(!cap1.isOpened())
    {
        // mutex.unlock();
        return pos;
    }
    double count = cap1.get(CAP_PROP_FRAME_COUNT);
    double cur = cap1.get(CAP_PROP_POS_FRAMES);
    if(count>0.001)
        pos = cur/count;
    // mutex.unlock();
    return pos;
}

void XVideoThread::SetBegin(double p)
{
    mutex.lock();
    double count = cap1.get(CAP_PROP_FRAME_COUNT);
    int frame = p*count;
    begin = frame;
    mutex.unlock();
}
void XVideoThread::SetEnd(double p)
{
    mutex.lock();
    double count = cap1.get(CAP_PROP_FRAME_COUNT);
    int frame = p*count;
    end = frame;
    mutex.unlock();
}

bool XVideoThread::Seek(int frame)
{
    mutex.lock();
    if(!cap1.isOpened())
    {

        mutex.unlock();
        return false;
    }

    int re = cap1.set(CAP_PROP_POS_FRAMES,frame);
    if(cap2.isOpened()){
        cap2.set(CAP_PROP_POS_FRAMES,frame);
    }

    mutex.unlock();
    return re;

}

bool XVideoThread::Seek(double pos)
{
    double count = cap1.get(CAP_PROP_FRAME_COUNT);
    int frame = pos*count;
    return Seek(frame);

}
//开始导出
bool XVideoThread::StartSave(const std::string filename, int width, int height,bool isColor)
{
    // Seek(0);
    Seek(begin);
    mutex.lock();
    if(!cap1.isOpened())
    {
        mutex.unlock();
        return false;
    }
    if(width<=0)
        width = cap1.get(CAP_PROP_FRAME_WIDTH);
    if(height<=0)
        height = cap1.get(CAP_PROP_FRAME_HEIGHT);

    vw.open(filename,VideoWriter::fourcc('x','2','6','4'),this->fps,Size(width,height),isColor);

    if(!vw.isOpened())
    {
        std::cout<<"start save failed!"<<std::endl;
        mutex.unlock();
        return false;
    }
    isWrite = true;
    desFile = filename;
    mutex.unlock();
    return true;
}

//导出结束
void XVideoThread::StopSave()
{
    mutex.lock();
    vw.release();
    isWrite = false;
    mutex.unlock();

}


void XVideoThread::play()
{
    mutex.lock();
    isPlay =true;
    mutex.unlock();
}

void XVideoThread::stop()
{
    mutex.lock();
    isPlay = false;
    mutex.unlock();
}

void XVideoThread::SetMark(Mat mark)
{
    mutex.lock();
    this->mark = mark;


    mutex.unlock();


}


XVideoThread::XVideoThread() {
    start();
}

XVideoThread::~XVideoThread()
{
    if(!this->isInterruptionRequested())
    {
        {
            // QMutexLocker lock(&mutex);
            mutex.lock();
            isExit = true;
            mutex.unlock();
        }
        this->requestInterruption();
        this->wait();
    }
}

void XVideoThread::run()
{
    Mat mat1;

    isExit =false;
    while(!isExit){
        mutex.lock();
        if(!cap1.isOpened()){
            mutex.unlock();
            msleep(5);
            continue;
        }
        if(!isPlay)
        {
            mutex.unlock();
            msleep(5);
            continue;
        }
        int cur = cap1.get(CAP_PROP_POS_FRAMES);
        if((end >0 && cur>= end) ||!cap1.read(mat1) ||mat1.empty()){
            mutex.unlock();
            //导出到结尾位置，停止导出
            if(isWrite)
            {
                StopSave();
                SaveEnd();
            }
            msleep(5);
            continue;
        }
        Mat mat2 =mark;
        //显示图像
        if(!isWrite)
        {
            emit(ViewImage1(mat1));
        }

        if(cap2.isOpened())
        {
            cap2.read(mat2);
            emit(ViewImage2(mat2));
        }

        Mat des = XFilter::Get()->Filter(mat1,mat2);
        if(!isWrite)
        {
            emit(ViewDes(des));
        }
        int s =0;
        s =1000/fps;

        if(isWrite)
        {
            s=1;
            vw.write(des);
        }
        // msleep(30);
        msleep(s);
        mutex.unlock();
    }
}
